package com.springlearn.springsourcecode.chap16;

import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Method;

/**
 * @author wtcode
 * @Description
 * @date 2025/4/8 - 9:07
 */
public class A16 {

    public static void main(String[] args) throws NoSuchMethodException{

        AspectJExpressionPointcut pt1 = new AspectJExpressionPointcut();
        pt1.setExpression("execution(* bar())");
        System.out.println(pt1.matches(T1.class.getMethod("bar"),T1.class));
        System.out.println(pt1.matches(T1.class.getMethod("foo"),T1.class));


        AspectJExpressionPointcut pt2 = new AspectJExpressionPointcut();
        pt2.setExpression("@annotation(org.springframework.transaction.annotation.Transactional)");
        System.out.println(pt2.matches(T1.class.getMethod("bar"),T1.class));
        System.out.println(pt2.matches(T1.class.getMethod("foo"),T1.class));


        StaticMethodMatcherPointcut pt3 = new StaticMethodMatcherPointcut() {
            @Override
            public boolean matches(Method method, Class<?> targetClass) {
                // 检查方法上是否加上了@Transactional注解
                MergedAnnotations annotationsMethod = MergedAnnotations.from(method);
                if(annotationsMethod.isPresent(Transactional.class)){
                    return true;
                }
                // 检查类上是否加了@Transactional注解
                MergedAnnotations annotationsClass = MergedAnnotations.from(targetClass);
                if(annotationsClass.isPresent(Transactional.class)){
                    return true;
                }
                return false;
            }
        };
        System.out.println(pt3.matches(T1.class.getMethod("foo"), T1.class));
    }

    static class T1{
        @Transactional
        public void foo(){}

        public void bar(){}

    }

    @Transactional
    static class T2{
        public void foo(){}
    }

    @Transactional
    interface I3{
        void foo();
    }

    static class T3 implements I3{
        @Override
        public void foo() {

        }
    }

}
